/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.identity.domain;

import com.jb.framework.database.Predicate;
import com.jb.web.context.WebContext;
import com.jb.web.model.DBDescriptor;
import com.jb.framework.ModelBean;

import com.jb.framework.PersistentManagerRegistry;

import java.util.Date;
import java.util.List;


/**
 * Defines a relationship between two parties.
 *
 * @author Tim Wang
 * @version 1.0
 */
public class Friendship extends ModelBean {
    private static final int INVITED = 0;
    private static final int ACCEPTED = 1;
    private static final int INVITE = 2;
    private static final int DELETED = -1;
    private String myId;
    private String friendId;
    private String myName;
    private String friendName;
    private String nickName;
    private String typeOfRelationship;
    private float weight;
    private int status;
    UserAccount userAccount = null;

    /**
     * Lists friends for the given user
     *
     * @param userId whose friends to be lised
     *
     * @return list of friendships
     */
    public static List getFriends(String userId) {
        return PersistentManagerRegistry.find(Friendship.class,
            new Predicate(new Predicate("myId", userId, "="),
                new Predicate("status", "" + ACCEPTED, "="), "and"));
    }

    /**
     * Lists invitations for a given user name. This is a database
     * finder.
     *
     * @param userId whos invitation to be listed
     *
     * @return List of friends that has invited the user.
     */
    public static List getInvitations(String userId) {
        return PersistentManagerRegistry.find(com.jb.identity.domain.Friendship.class,
            new Predicate(new Predicate("friendId", userId, "="),
                new Predicate("status", "" + INVITED, "="), "and"));
    }


    public static List getPendingInvitations(String userId) {
        return PersistentManagerRegistry.find(com.jb.identity.domain.Friendship.class,
            new Predicate(new Predicate("myId", userId, "="),
                new Predicate("status", "" + INVITED, "="), "and"));
    }


    public boolean isAccepted() {
        return status == ACCEPTED;
    }

    public static Friendship getFriendShip(String invitee, String invited) {
        List list = PersistentManagerRegistry.find(com.jb.identity.domain.Friendship.class,
                new Predicate(new Predicate("myid", invitee, "="),
                    new Predicate("friendid", invited, "="), "and"));

        return (list.size() == 0) ? null : (Friendship) list.get(0);
    }

    /**
     * Confirms the friendship.
     */

    //called through accept api
    public void confirmFriendShip(WebContext ctx, String inviteeId,
        String invitedId) {
        Friendship friend = getFriendShip(invitedId, inviteeId);

        if (friend != null) {
            friend.setStatus(ACCEPTED);
            friend.update(ctx);

            setStatus(ACCEPTED);
            update(ctx);
        }
    }

    /**
     * Creates a friendship for to people.
     * @param ctx
     * @param invitee
     * @param invited
     * @param type
     * @return
     */
    public static Friendship createFriendShip(WebContext ctx,
        UserAccount invitee, UserAccount invited, String type) {
        Friendship friend = getFriendShip(invitee.getId(), invited.getId());

        //you are already a friend
        if (friend != null) {
            friend.confirmFriendShip(ctx, invitee.getId(), invited.getId());

            return friend;
        }

        friend = new Friendship();
        friend.setMyId(invitee.getId());
        friend.setFriendId(invited.getId());
        friend.setFriendName(invited.getScreenName());
        friend.setMyName(invitee.getScreenName());
        friend.setTypeOfRelationship(type);

        // friend.setNickName(invitee + "and" + invited);
        friend.setStartDate(new Date());
        friend.setStatus(INVITED);
        friend.update(ctx);

        Friendship invitation = new Friendship();
        invitation.setMyId(invited.getId());
        invitation.setFriendId(invitee.getId());
        invitation.setTypeOfRelationship(type);
        invitation.setFriendName(invitee.getScreenName());
        invitation.setMyName(invited.getScreenName());

        //invitation.setNickName(invited + "and" + invitee);
        invitation.setStartDate(new Date());
        invitation.setStatus(INVITE);

        invitation.update(ctx);
        friend.update(ctx);

        return friend;
    }

    /**
     * Deletes a friendship
     *
     * @param ctx DOCUMENT ME!
     * @param u1 DOCUMENT ME!
     * @param u2 DOCUMENT ME!
     * @param type DOCUMENT ME!
     */
    public static void deleteFriendShip(WebContext ctx, UserAccount u1,
        UserAccount u2, String type) {
        Friendship friendship = u1.getFriend(u2.getId());
        friendship.delete(ctx);
        friendship = u2.getFriend(u1.getId());
        friendship.setStatus(DELETED);
        friendship.update(ctx);
    }


    public void setTypeOfRelationship(String typeOfRelationship) {
        this.typeOfRelationship = typeOfRelationship;
    }

    public String getTypeOfRelationship() {
        return typeOfRelationship;
    }
    
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }


    public String getNickName() {
        return nickName;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }

    public float getWeight() {
        return weight;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }

    public UserAccount getFriend() {
        if (userAccount == null) {
            userAccount = (UserAccount) PersistentManagerRegistry.findById(UserAccount.class, friendId);
        }

        return userAccount;
    }

    public void setMyId(String myId) {
        this.myId = myId;
    }

    public String getMyId() {
        return myId;
    }

    public void setFriendId(String friendId) {
        this.friendId = friendId;
    }

    public String getFriendId() {
        return friendId;
    }

    public void setMyName(String myName) {
        this.myName = myName;
    }

    public String getMyName() {
        return myName;
    }

    public void setFriendName(String friendName) {
        this.friendName = friendName;
    }

    public String getFriendName() {
        return friendName;
    }
    
    static class _DD extends DBDescriptor {
        static {
            PersistentManagerRegistry.registerDescriptor(Friendship.class, new _DD());
        }
        _DD() {
            addIndex("relation", new String[] { "friendid, myid, status" });
        }
    }
    
}
